package ar.com.jwa.services.impl;

import java.util.Collection;

import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import ar.com.jwa.domain.Game;
import ar.com.jwa.domain.State;
import ar.com.jwa.domain.User;
import ar.com.jwa.services.GameLocalService;
import ar.com.jwa.services.UserLocalService;

public class GameLocalServiceImpl extends JpaDaoSupport implements GameLocalService {
	
	@Autowired
	private UserLocalService userLocalService;
	
	private EntityManagerFactory entityManagerFactory;
	

	@Transactional
	public void saveGame(Game game) {
		this.logger.info("trying to persist Game entity");
		getJpaTemplate().merge(game);
	}
	
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public Game getGameById(String gameId) {
		return getGameById(new Long(gameId));
	}
	
	
	@Transactional(propagation = Propagation.REQUIRED)
	public Game getGameById(Long gameId) {
		this.logger.info("Searching game by id : " + gameId);
		return this.getJpaTemplate().find(Game.class, gameId);
	}
	
	
	@Override
	@Transactional
	public Collection<Game> getAllGamesToConfirm() {
		Collection<Game> games = getJpaTemplate().find("select G FROM ar.com.jwa.domain.Game G where G.state =?1",State.TO_CONFIRM);
		return games;
	}
	
	
	@Override
	@Transactional
	public Collection<Game> getGamesToConfirmByUser(String userId) {
		User user = this.getUserLocalService().getUserById(new Long(userId));
		if (user != null)
			return getGamesToConfirmGByUser(user);
		return null;
	}
	
	
	@Override
	@Transactional
	public Collection<Game> getGamesToConfirmGByUser(User user) {
		Collection<Game> games = null;
		if (user != null){
			games = getJpaTemplate().find("select G FROM ar.com.jwa.domain.Game G where G.state = ?1 and G.theDate > CURDATE() and ?2  in elements(G.players)",State.TO_CONFIRM,user);
		}
		return games;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	public Collection<Game> getGamesByState(State state) {
		
		return this.getJpaTemplate().find("select G FROM ar.com.jwa.domain.Game G where G.state = ?1 ", state);
		
	}
	
	
	@Override
	@Transactional
	public Collection<Game> getGamesByState(State state, String userId){
		try {
			
			User user  = this.getUserLocalService().getUserById(new Long(userId));
			return this.getGamesByState(state, user);
			
		} catch (Exception e) {
			this.logger.error(e.getMessage());
			throw new PersistenceException(e.getMessage());
			
		}
	}
	
	@Override
	@Transactional
	public Collection<Game> getGamesByState(State state,User user) {
//		return getJpaTemplate().find("select G FROM ar.com.jwa.domain.Game G where G.state = ?1 and G.theDate > CURDATE() and ?2  in elements(G.confirmedPlayers)",state,user);
		return getJpaTemplate().find("select G FROM ar.com.jwa.domain.Game G where G.state = ?1 and G.theDate > CURDATE()",state);
	}
	
	/**
	 * @return the userLocalService
	 */
	public UserLocalService getUserLocalService() {
		return userLocalService;
	}

	/**
	 * @param userLocalService the userLocalService to set
	 */
	public void setUserLocalService(UserLocalService userLocalService) {
		this.userLocalService = userLocalService;
	}

	/**
	 * @return the entityManagerFactory
	 */
	public EntityManagerFactory getEntityManagerFactory() {
		return entityManagerFactory;
	}


}
